package com.ztorn.fiscale.controller;

import java.util.List;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ztorn.common.core.web.controller.BaseController;
import com.ztorn.common.core.web.page.TableDataInfo;
import com.ztorn.common.core.web.domain.AjaxResult;
import com.ztorn.fiscale.domain.FiscaleRefundMatching;
import com.ztorn.fiscale.domain.FiscaleRefundException;
import com.ztorn.fiscale.domain.FiscaleRefundBatch;
import com.ztorn.fiscale.domain.FiscaleRefundBatchDetail;
import com.ztorn.fiscale.domain.FiscaleCustomsDeclaration;
import com.ztorn.fiscale.domain.FiscaleTaxInvoice;
import com.ztorn.fiscale.service.IFiscaleRefundMatchingService;
import com.ztorn.fiscale.service.IFiscaleRefundExceptionService;
import com.ztorn.fiscale.service.IFiscaleRefundBatchService;
import com.ztorn.fiscale.service.IFiscaleRefundBatchDetailService;
import com.ztorn.fiscale.service.IFiscaleCustomsDeclarationService;
import com.ztorn.fiscale.service.IFiscaleTaxInvoiceService;

/**
 * 退税管理Controller
 *
 * @author ztorn
 * @date 2025-09-20
 */
@RestController
@RequestMapping("/refund")
public class RefundManagementController extends BaseController
{
    @Autowired
    private IFiscaleRefundMatchingService fiscaleRefundMatchingService;

    @Autowired
    private IFiscaleRefundExceptionService fiscaleRefundExceptionService;

    @Autowired
    private IFiscaleRefundBatchService fiscaleRefundBatchService;

    @Autowired
    private IFiscaleRefundBatchDetailService fiscaleRefundBatchDetailService;

    @Autowired
    private IFiscaleCustomsDeclarationService fiscaleCustomsDeclarationService;

    @Autowired
    private IFiscaleTaxInvoiceService fiscaleTaxInvoiceService;

    /**
     * 查询待配单列表
     */
    @GetMapping("/pendingMatching")
    public TableDataInfo listPendingMatching()
    {
        // 查询未匹配的报关单和发票
        List<FiscaleRefundMatching> list = new ArrayList<>();

        // 查询未匹配的报关单
        FiscaleCustomsDeclaration declarationQuery = new FiscaleCustomsDeclaration();
        declarationQuery.setCustomsStatus("approved"); // 已审核的报关单
        List<FiscaleCustomsDeclaration> declarations = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationList(declarationQuery);

        // 查询未匹配的发票
        FiscaleTaxInvoice invoiceQuery = new FiscaleTaxInvoice();
        invoiceQuery.setStatus("issued"); // 已开具的发票
        List<FiscaleTaxInvoice> invoices = fiscaleTaxInvoiceService.selectFiscaleTaxInvoiceList(invoiceQuery);

        // 将报关单和发票转换为配单记录格式
        for (FiscaleCustomsDeclaration declaration : declarations) {
            FiscaleRefundMatching matching = new FiscaleRefundMatching();
            matching.setDeclaration(declaration);
            matching.setStatus("pending"); // 待配单状态
            list.add(matching);
        }

        for (FiscaleTaxInvoice invoice : invoices) {
            FiscaleRefundMatching matching = new FiscaleRefundMatching();
            matching.setInvoice(invoice);
            matching.setStatus("pending"); // 待配单状态
            list.add(matching);
        }

        return getDataTable(list);
    }

    /**
     * 查询未匹配的报关单列表（用于配单异常页面）
     */
    @GetMapping("/unmatchedDeclarations")
    public TableDataInfo listUnmatchedDeclarations(FiscaleCustomsDeclaration declaration)
    {
        startPage();
        // 只查询已审核但未匹配的报关单
        declaration.setCustomsStatus("");
        List<FiscaleCustomsDeclaration> list = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationList(declaration);
        return getDataTable(list);
    }

    /**
     * 查询未匹配的发票列表（用于配单异常页面）
     */
    @GetMapping("/unmatchedInvoices")
    public TableDataInfo listUnmatchedInvoices(FiscaleTaxInvoice invoice)
    {
        startPage();
        // 只查询已开具但未匹配的发票
        invoice.setStatus("已开具");
        List<FiscaleTaxInvoice> list = fiscaleTaxInvoiceService.selectFiscaleTaxInvoiceList(invoice);
        return getDataTable(list);
    }

    /**
     * 查询已配单列表
     */
    @GetMapping("/matched")
    public TableDataInfo listMatched(FiscaleRefundMatching matching)
    {
        startPage();
        List<FiscaleRefundMatching> list = fiscaleRefundMatchingService.selectFiscaleRefundMatchingList(matching);
        return getDataTable(list);
    }

    /**
     * 查询配单异常列表
     */
    @GetMapping("/exceptions")
    public TableDataInfo listExceptions(FiscaleRefundException exception)
    {
        startPage();
        List<FiscaleRefundException> list = fiscaleRefundExceptionService.selectFiscaleRefundExceptionList(exception);
        return getDataTable(list);
    }

    /**
     * 取消配对
     */
    @PutMapping("/cancelMatching/{matchingId}")
    public AjaxResult cancelMatching(@PathVariable Long matchingId)
    {
        try {
            int result = fiscaleRefundMatchingService.cancelMatching(matchingId);
            if (result > 0) {
                return AjaxResult.success("取消配对成功");
            } else {
                return AjaxResult.error("取消配对失败");
            }
        } catch (Exception e) {
            return AjaxResult.error("取消配对失败：" + e.getMessage());
        }
    }

    /**
     * 智能推荐
     */
    @PostMapping("/recommend")
    public AjaxResult recommendMatching(@RequestBody Long declarationId)
    {
        try {
            // 根据报关单信息推荐最匹配的发票
            // 这里简化处理，实际应该根据金额、商品、时间等规则计算匹配度
            List<FiscaleRefundMatching> recommendations = new ArrayList<>();

            // 查询报关单信息
            FiscaleCustomsDeclaration declaration = fiscaleCustomsDeclarationService.selectFiscaleCustomsDeclarationByDeclarationId(declarationId);
            if (declaration != null) {
                // 查询未匹配的发票
                FiscaleTaxInvoice query = new FiscaleTaxInvoice();
                query.setStatus("issued"); // 已开具的发票
                List<FiscaleTaxInvoice> invoices = fiscaleTaxInvoiceService.selectFiscaleTaxInvoiceList(query);

                // 根据金额匹配度推荐1-3个最可能匹配的发票
                for (FiscaleTaxInvoice invoice : invoices) {
                    // 简化处理，只推荐金额相同的发票
                    if (invoice.getTotalAmount().compareTo(declaration.getTotalAmount()) == 0) {
                        FiscaleRefundMatching matching = new FiscaleRefundMatching();
                        matching.setDeclaration(declaration);
                        matching.setInvoice(invoice);
                        recommendations.add(matching);

                        // 最多推荐3个
                        if (recommendations.size() >= 3) {
                            break;
                        }
                    }
                }
            }

            return AjaxResult.success("推荐成功", recommendations);
        } catch (Exception e) {
            return AjaxResult.error("推荐失败：" + e.getMessage());
        }
    }

    /**
     * 手动关联
     */
    @PostMapping("/manualMatching")
    public AjaxResult manualMatching(@RequestBody ManualMatchingRequest request)
    {
        try {
            int result = fiscaleRefundMatchingService.manualMatching(
                request.getDeclarationId(),
                request.getInvoiceId(),
                request.getMatchReason()
            );
            if (result > 0) {
                return AjaxResult.success("手动关联成功");
            } else {
                return AjaxResult.error("手动关联失败，可能已存在关联关系");
            }
        } catch (Exception e) {
            return AjaxResult.error("手动关联失败：" + e.getMessage());
        }
    }

    /**
     * 标记为异常
     */
    @PostMapping("/markException")
    public AjaxResult markException(@RequestBody MarkExceptionRequest request)
    {
        try {
            int result = fiscaleRefundExceptionService.markAsException(
                request.getDocumentType(),
                request.getDocumentId(),
                request.getExceptionReason(),
                request.getRemark()
            );
            if (result > 0) {
                return AjaxResult.success("标记异常成功");
            } else {
                return AjaxResult.error("标记异常失败");
            }
        } catch (Exception e) {
            return AjaxResult.error("标记异常失败：" + e.getMessage());
        }
    }

    /**
     * 查询待申报退税列表
     */
    @GetMapping("/pendingDeclaration")
    public TableDataInfo listPendingDeclaration()
    {
        // 查询状态为"matched"且未申报的配单记录
        FiscaleRefundMatching query = new FiscaleRefundMatching();
        query.setStatus("matched");
        List<FiscaleRefundMatching> list = fiscaleRefundMatchingService.selectFiscaleRefundMatchingList(query);
        return getDataTable(list);
    }

    /**
     * 生成退税数据
     */
    @PostMapping("/generateRefundData")
    public AjaxResult generateRefundData(@RequestBody Long[] matchingIds)
    {
        try {
            FiscaleRefundBatch batch = fiscaleRefundBatchService.generateRefundData(matchingIds);
            if (batch != null) {
                return AjaxResult.success("生成退税数据成功", batch);
            } else {
                return AjaxResult.error("生成退税数据失败");
            }
        } catch (Exception e) {
            return AjaxResult.error("生成退税数据失败：" + e.getMessage());
        }
    }

    /**
     * 正式申报
     */
    @PostMapping("/submitRefundDeclaration/{batchId}")
    public AjaxResult submitRefundDeclaration(@PathVariable Long batchId)
    {
        try {
            int result = fiscaleRefundBatchService.submitRefundDeclaration(batchId);
            if (result > 0) {
                return AjaxResult.success("提交申报成功");
            } else {
                return AjaxResult.error("提交申报失败");
            }
        } catch (Exception e) {
            return AjaxResult.error("提交申报失败：" + e.getMessage());
        }
    }

    /**
     * 查询退税申报批次列表
     */
    @GetMapping("/batches")
    public TableDataInfo listBatches(FiscaleRefundBatch batch)
    {
        startPage();
        List<FiscaleRefundBatch> list = fiscaleRefundBatchService.selectFiscaleRefundBatchList(batch);
        return getDataTable(list);
    }

    /**
     * 获取退税申报批次详情
     */
    @GetMapping("/batches/{batchId}")
    public AjaxResult getBatchDetail(@PathVariable Long batchId)
    {
        FiscaleRefundBatch batch = fiscaleRefundBatchService.selectFiscaleRefundBatchById(batchId);
        if (batch == null) {
            return AjaxResult.error("批次不存在");
        }

        // 获取明细信息
        List<FiscaleRefundBatchDetail> details = fiscaleRefundBatchDetailService.selectFiscaleRefundBatchDetailListByBatchId(batchId);
        batch.setBatchDetails(details);

        return AjaxResult.success(batch);
    }

    /**
     * 刷新申报状态
     */
    @PutMapping("/refreshStatus/{batchId}")
    public AjaxResult refreshStatus(@PathVariable Long batchId)
    {
        try {
            int result = fiscaleRefundBatchService.refreshRefundStatus(batchId);
            if (result > 0) {
                return AjaxResult.success("刷新状态成功");
            } else {
                return AjaxResult.error("刷新状态失败");
            }
        } catch (Exception e) {
            return AjaxResult.error("刷新状态失败：" + e.getMessage());
        }
    }

    /**
     * 下载回执
     */
    @GetMapping("/downloadReceipt/{batchId}")
    public AjaxResult downloadReceipt(@PathVariable Long batchId)
    {
        try {
            FiscaleRefundBatch batch = fiscaleRefundBatchService.selectFiscaleRefundBatchById(batchId);
            if (batch == null) {
                return AjaxResult.error("批次不存在");
            }

            // 实际实现中应该返回回执文件
            // 这里只是模拟返回回执信息
            return AjaxResult.success("回执文件下载链接生成成功", batch.getTaxAuthorityReceipt());
        } catch (Exception e) {
            return AjaxResult.error("生成回执文件下载链接失败：" + e.getMessage());
        }
    }

    /**
     * 手动关联请求对象
     */
    public static class ManualMatchingRequest {
        private Long declarationId;
        private Long invoiceId;
        private String matchReason;

        public Long getDeclarationId() {
            return declarationId;
        }

        public void setDeclarationId(Long declarationId) {
            this.declarationId = declarationId;
        }

        public Long getInvoiceId() {
            return invoiceId;
        }

        public void setInvoiceId(Long invoiceId) {
            this.invoiceId = invoiceId;
        }

        public String getMatchReason() {
            return matchReason;
        }

        public void setMatchReason(String matchReason) {
            this.matchReason = matchReason;
        }
    }

    /**
     * 标记异常请求对象
     */
    public static class MarkExceptionRequest {
        private String documentType;
        private Long documentId;
        private String exceptionReason;
        private String remark;

        public String getDocumentType() {
            return documentType;
        }

        public void setDocumentType(String documentType) {
            this.documentType = documentType;
        }

        public Long getDocumentId() {
            return documentId;
        }

        public void setDocumentId(Long documentId) {
            this.documentId = documentId;
        }

        public String getExceptionReason() {
            return exceptionReason;
        }

        public void setExceptionReason(String exceptionReason) {
            this.exceptionReason = exceptionReason;
        }

        public String getRemark() {
            return remark;
        }

        public void setRemark(String remark) {
            this.remark = remark;
        }
    }
}
